/*
 * Copyright (C) 2011 Olivier Pothin and contributors
 *
 * GNU General Public License v2.0
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */


/**
 * 
 * @author Olivier Pothin
 *
 */

package opot.utils;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Random;
import java.util.Set;

import opot.db.WordProvider;
import opot.dto.Question;
import opot.dto.Stat;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.net.Uri;
import android.util.Log;

public class QuizzController implements QuizzInterface {

	private int[] mQuestions;
	private int questionCursor;
	private  int nbWordsID;
	private  int range;
	private static QuizzController mQuizzController;
	//set (unique key) that manage the questions for this quizz session
	private Set<Integer> holder;
	private Iterator<Integer> wordIterator;

	//** used to retrieve new stat session */
	private	UriMatcher sUriMatcher;
	private static final int STATS_ID= 1;
	private String currentStatSession;
	private Context m_ctx;


	private QuizzController(){
		sUriMatcher	=  new UriMatcher(UriMatcher.NO_MATCH);
		sUriMatcher.addURI(WordProvider.AUTHORITY, "stats/#", STATS_ID);
	}

	public static QuizzController getInstance(){
		if (mQuizzController == null)
			mQuizzController = new QuizzController();
		return mQuizzController;
	}

	public QuizzController initialise(int nbElement,int range,Context ctx) {
		//SAVE CURRENT SESSION TO DATABASE FOR STATS

		this.nbWordsID = nbElement;
		this.range = range;
		questionCursor = -1;
		holder = new LinkedHashSet<Integer>(nbWordsID);
		fillHolder();
		wordIterator = holder.iterator();
		mQuestions = new int[nbWordsID];
		storeInit(ctx);
		return this;
	}

	private void fillHolder() {
		Random generator = new Random();
		int next;
		while(holder.size() < nbWordsID) {
			next = generator.nextInt(range)+1;
			holder.add(next);
		}
	}

	/** Le quizz est-il fini ? **/
	public boolean isFinished(){
		return ! wordIterator.hasNext();
	}

	/**
	 * La question en cours est-elle finie ?
	 * @return
	 */

	public boolean isQuestionFinished() {
		Log.d("QUESTION STATE","QSTATE : "+getQuestionState()+" ET CUSRIR = "+questionCursor);
		return (getQuestionState() == Question.FAIL || getQuestionState() == Question.SUCCESS);
	}

	public int getNextQuestion() {
		questionCursor++;
		mQuestions[questionCursor] = Question.INITIAL_STATE;
		return wordIterator.next();
	}

	private int getQuestionState() {
		if(questionCursor < 0)
			return Question.INITIAL_STATE;
		return mQuestions[questionCursor];

	}

	//le nombre de chances restantespour la question courante
	public int getNbChancesForQuestion() {
		return getQuestionState();
	}

	public int badAnswer() {
		if ( mQuestions[questionCursor] != Question.FAIL)
			mQuestions[questionCursor] = mQuestions[questionCursor]-1;
		return mQuestions[questionCursor];
	}

	public void goodAnswer() {
		mQuestions[questionCursor] = Question.SUCCESS;
	}

	public int getCurrentAnswer() {
		return mQuestions[questionCursor];
	}

	public String getScore(){
		int questionsOK = 0;
		int questionsKO = 0;
		for(int ques : mQuestions) {
			switch(ques){
			case Question.SUCCESS:
				questionsOK++;
				break;

			case Question.FAIL:
				questionsKO++;
				break;
			}
		}

		this.save(questionsOK,questionsKO);
		return ""+questionsOK+"/"+nbWordsID;
	}

	private void save(int questionsOK,int questionsKO){

		if(currentStatSession != null){
			//At least a quizz was initialized
			Long now = Long.valueOf(System.currentTimeMillis());
			ContentValues values = new ContentValues();
			values.put(Stat.Stats.COLUMN_NAME_NB_GOOD_ANSWER,questionsOK);
			values.put(Stat.Stats.COLUMN_NAME_NB_BAD_ANSWER,questionsKO);
			values.put(Stat.Stats.COLUMN_NAME_END_DATE, now);
			
			Uri row = Uri.parse("content://"+WordProvider.AUTHORITY+"/stats/"+currentStatSession);
			m_ctx.getContentResolver().update(row, values, null, null);
		}

	}

	public void storeInit(Context ctx) {

		m_ctx = ctx;
		
		ContentValues values = new ContentValues();

		values.put(Stat.Stats.COLUMN_NAME_DIFFICULTY, 20);
		values.put(Stat.Stats.COLUMN_NAME_NB_QUESTIONS, nbWordsID);
		values.put(Stat.Stats.COLUMN_NAME_NB_GOOD_ANSWER, 0);
		values.put(Stat.Stats.COLUMN_NAME_END_DATE, 0);
		values.put(Stat.Stats.COLUMN_NAME_NB_BAD_ANSWER, 0);

		Uri current = m_ctx.getContentResolver().insert(Stat.Stats.CONTENT_URI, values);
		switch(sUriMatcher.match(current)) {
		case STATS_ID:
			currentStatSession = current.getPathSegments().get(Stat.Stats.PATH_STATS_ID_POSITION);
			break;
		}

	}
}
